<template>
  <div class="menu-management-page">
    <el-card class="main-card">
      <template #header>
        <div class="card-header">
          <h3>菜单管理</h3>
          <div class="actions">
            <el-button type="primary" :icon="Plus" @click="handleAdd">新增菜单</el-button>
            <el-button type="success" :icon="Refresh" @click="handleRefresh" :loading="tableLoading">刷新列表</el-button>
          </div>
        </div>
      </template>
      
      <div class="search-container">
        <el-form :inline="true" :model="searchForm">
          <el-form-item label="菜单名称">
            <el-input v-model="searchForm.menuName" placeholder="请输入菜单名称" clearable @keyup.enter="handleSearch" style="width: 200px" />
          </el-form-item>
          <el-form-item label="菜单类型">
            <el-select v-model="searchForm.menuType" placeholder="请选择菜单类型" clearable style="width: 200px">
              <el-option label="目录" :value="0" />
              <el-option label="菜单" :value="1" />
              <el-option label="按钮" :value="2" />
            </el-select>
          </el-form-item>
          <el-form-item label="状态">
            <el-select v-model="searchForm.status" placeholder="请选择状态" clearable style="width: 200px">
              <el-option label="启用" :value="1" />
              <el-option label="禁用" :value="0" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" :icon="Search" @click="handleSearch" :loading="tableLoading">搜索</el-button>
            <el-button :icon="Refresh" @click="handleReset">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
      
      <div class="table-container">
        <el-table
          :data="filteredMenuTree"
          row-key="id"
          :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
          border
          stripe
          style="width: 100%"
          v-loading="tableLoading"
        >
          <el-table-column prop="name" label="菜单名称" min-width="200" show-overflow-tooltip>
            <template #default="{ row }">
              <span style="display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;">
                <el-icon v-if="row.icon" class="menu-icon">
                  <component :is="row.icon" />
                </el-icon>
                {{ row.name }}
              </span>
            </template>
          </el-table-column>
          
          <el-table-column prop="menuType" label="菜单类型" width="100" align="center">
            <template #default="{ row }">
              <el-tag
                v-if="row.menuType === 0"
                size="small"
              >目录</el-tag>
              <el-tag
                v-else-if="row.menuType === 1"
                type="success"
                size="small"
              >菜单</el-tag>
              <el-tag
                v-else-if="row.menuType === 2"
                type="warning"
                size="small"
              >按钮</el-tag>
            </template>
          </el-table-column>
          
          <el-table-column prop="path" label="路由路径" min-width="150">
            <template #default="{ row }">
              <span>{{ row.path || '-' }}</span>
            </template>
          </el-table-column>
          
          <el-table-column prop="component" label="组件路径" min-width="150">
            <template #default="{ row }">
              <span>{{ row.component || '-' }}</span>
            </template>
          </el-table-column>
          
          <el-table-column prop="permission" label="权限标识" min-width="150">
            <template #default="{ row }">
              <span>{{ row.permission || '-' }}</span>
            </template>
          </el-table-column>
          
          <el-table-column prop="sort" label="排序" width="80" align="center" />
          
          <el-table-column prop="status" label="状态" width="80" align="center" class-name="status-column">
            <template #default="{ row }">
              <el-tag
                v-if="row.status === 1"
                type="success"
                size="small"
              >启用</el-tag>
              <el-tag
                v-else
                type="danger"
                size="small"
              >禁用</el-tag>
            </template>
          </el-table-column>
          
          <el-table-column label="操作" width="200" align="center" fixed="right" class-name="action-column">
            <template #default="{ row }">
              <el-button size="small" @click="handleAddChild(row)" :disabled="deleteLoading">添加</el-button>
              <el-button size="small" @click="handleEdit(row)" :disabled="deleteLoading">编辑</el-button>
              <el-button size="small" type="danger" @click="handleDelete(row)" :loading="deleteLoading && currentDeleteId === row.id">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-card>
    
    <!-- 菜单编辑对话框 -->
    <el-dialog
      :title="dialogTitle"
      v-model="dialogVisible"
      width="600px"
      @close="handleDialogClose"
    >
      <el-form
        :model="menuForm"
        :rules="menuRules"
        ref="menuFormRef"
        label-width="100px"
      >
        <el-form-item label="菜单类型" prop="menuType">
          <el-radio-group v-model="menuForm.menuType">
            <el-radio :label="0">目录</el-radio>
            <el-radio :label="1">菜单</el-radio>
            <el-radio :label="2">按钮</el-radio>
          </el-radio-group>
        </el-form-item>
        
        <el-form-item label="上级菜单" prop="parentId">
          <el-tree-select
            v-model="menuForm.parentId"
            :data="menuOptions"
            node-key="id"
            :props="{ label: 'name', children: 'children' }"
            value-key="id"
            check-strictly
            clearable
            placeholder="请选择上级菜单"
            style="width: 100%"
          />
        </el-form-item>
        
        <el-form-item label="菜单名称" prop="name">
          <el-input v-model="menuForm.name" placeholder="请输入菜单名称" />
        </el-form-item>
        
        <el-form-item label="路由路径" prop="path" v-if="menuForm.menuType !== 2">
          <el-input v-model="menuForm.path" placeholder="请输入路由路径" />
        </el-form-item>
        
        <el-form-item label="组件路径" prop="component" v-if="menuForm.menuType === 1">
          <el-input v-model="menuForm.component" placeholder="请输入组件路径，如：/UserManagement" />
        </el-form-item>
        
        <el-form-item label="菜单图标" prop="icon" v-if="menuForm.menuType !== 2">
          <el-select v-model="menuForm.icon" placeholder="请选择图标" clearable filterable style="width: 100%">
            <el-option
              v-for="icon in iconOptions"
              :key="icon.value"
              :label="icon.label"
              :value="icon.value"
            >
              <div style="display: flex; align-items: center; gap: 8px;">
                <el-icon><component :is="icon.value" /></el-icon>
                <span>{{ icon.label }}</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
        
        <el-form-item label="权限标识" prop="permission" v-if="menuForm.menuType === 2">
          <el-input v-model="menuForm.permission" placeholder="请输入权限标识，如：sys:user:list" />
        </el-form-item>
        
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="menuForm.sort" :min="0" />
        </el-form-item>
        
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="menuForm.status">
            <el-radio :label="1">启用</el-radio>
            <el-radio :label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false" :disabled="submitLoading">取消</el-button>
          <el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed, getCurrentInstance } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Refresh, Search } from '@element-plus/icons-vue'
import { getAllMenusApi, saveMenuApi, deleteMenuApi } from '@/api/menu'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

// 数据相关
const menuTree = ref<any[]>([])
const filteredMenuTree = ref<any[]>([])
const dialogVisible = ref(false)
const dialogTitle = ref('')
const isEdit = ref(false)

// Loading状态
const tableLoading = ref(false)
const submitLoading = ref(false)
const deleteLoading = ref(false)
const currentDeleteId = ref<number | null>(null)

// 图标选项
const iconOptions = ref([
  { label: '用户', value: 'User' },
  { label: '设置', value: 'Setting' },
  { label: '文档', value: 'Document' },
  { label: '文件夹', value: 'Folder' },
  { label: '首页', value: 'House' },
  { label: '菜单', value: 'Menu' },
  { label: '管理', value: 'Tools' },
  { label: '数据', value: 'DataBoard' },
  { label: '图表', value: 'PieChart' },
  { label: '列表', value: 'List' },
  { label: '表格', value: 'Grid' },
  { label: '编辑', value: 'Edit' },
  { label: '删除', value: 'Delete' },
  { label: '添加', value: 'Plus' },
  { label: '搜索', value: 'Search' },
  { label: '刷新', value: 'Refresh' },
  { label: '下载', value: 'Download' },
  { label: '上传', value: 'Upload' },
  { label: '邮件', value: 'Message' },
  { label: '通知', value: 'Bell' },
  { label: '日历', value: 'Calendar' },
  { label: '时间', value: 'Clock' },
  { label: '位置', value: 'Location' },
  { label: '电话', value: 'Phone' },
  { label: '链接', value: 'Link' },
  { label: '标签', value: 'PriceTag' },
  { label: '收藏', value: 'Star' },
  { label: '分享', value: 'Share' },
  { label: '锁定', value: 'Lock' },
  { label: '解锁', value: 'Unlock' },
  { label: '眼睛', value: 'View' },
  { label: '隐藏', value: 'Hide' },
  { label: '帮助', value: 'QuestionFilled' },
  { label: '信息', value: 'InfoFilled' },
  { label: '警告', value: 'WarningFilled' },
  { label: '成功', value: 'SuccessFilled' },
  { label: '错误', value: 'CircleCloseFilled' },
  { label: '箭头右', value: 'ArrowRight' },
  { label: '箭头左', value: 'ArrowLeft' },
  { label: '箭头上', value: 'ArrowUp' },
  { label: '箭头下', value: 'ArrowDown' },
  { label: '更多', value: 'More' },
  { label: '关闭', value: 'Close' },
  { label: '检查', value: 'Check' },
  { label: '减号', value: 'Minus' },
  { label: '复制', value: 'CopyDocument' },
  { label: '粘贴', value: 'DocumentCopy' },
  { label: '保存', value: 'FolderAdd' },
  { label: '打印', value: 'Printer' },
  { label: '监控', value: 'Monitor' },
  { label: '服务器', value: 'Server' },
  { label: '数据库', value: 'Coin' },
  { label: '网络', value: 'Connection' },
  { label: '安全', value: 'Key' },
  { label: '权限', value: 'UserFilled' },
  { label: '角色', value: 'Avatar' },
  { label: '部门', value: 'OfficeBuilding' },
  { label: '组织', value: 'Operation' },
  { label: '流程', value: 'Sort' },
  { label: '审批', value: 'Finished' },
  { label: '统计', value: 'TrendCharts' },
  { label: '报表', value: 'DataAnalysis' },
  { label: '日志', value: 'Notebook' },
  { label: '配置', value: 'SetUp' },
  { label: '工具', value: 'Wrench' },
  { label: '插件', value: 'MagicStick' },
  { label: '扩展', value: 'Expand' },
  { label: '收缩', value: 'Fold' }
])

// 搜索表单
const searchForm = reactive({
  menuName: '',
  menuType: undefined as number | undefined,
  status: undefined as number | undefined
})

// 表单相关
const menuFormRef = ref()
const menuForm = reactive({
  id: undefined,
  name: '',
  path: '',
  component: '',
  icon: '',
  permission: '',
  menuType: 1,
  parentId: null,
  sort: 0,
  status: 1
})

const menuRules = {
  name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
  path: [{ required: true, message: '请输入路由路径', trigger: 'blur' }],
  component: [{ required: true, message: '请输入组件路径', trigger: 'blur' }]
}

// 菜单选项计算属性
const menuOptions = computed(() => {
  // 克隆菜单树
  const cloneMenuTree = (menus: any[]): any[] => {
    return menus.map(menu => ({
      ...menu,
      children: menu.children ? cloneMenuTree(menu.children) : []
    }))
  }
  
  // 禁用当前菜单及其子菜单
  const disableMenuAndChildren = (menus: any[], currentMenuId: any): any[] => {
    return menus.map(menu => {
      const disabled = menu.id === currentMenuId || isChildOfMenu(menu, currentMenuId, menuTree.value)
      return {
        ...menu,
        disabled,
        children: menu.children ? disableMenuAndChildren(menu.children, currentMenuId) : []
      }
    })
  }
  
  // 检查是否是某个菜单的子菜单
  const isChildOfMenu = (menu: any, parentId: any, allMenus: any[]): boolean => {
    for (const m of allMenus) {
      if (m.id === parentId) {
        return isDescendantOf(menu, m)
      }
      if (m.children && m.children.length > 0) {
        if (isChildOfMenu(menu, parentId, m.children)) {
          return true
        }
      }
    }
    return false
  }
  
  // 检查是否是后代
  const isDescendantOf = (menu: any, ancestor: any): boolean => {
    if (!ancestor.children) return false
    for (const child of ancestor.children) {
      if (child.id === menu.id) return true
      if (isDescendantOf(menu, child)) return true
    }
    return false
  }
  
  let clonedTree = cloneMenuTree(menuTree.value)
  
  if (isEdit.value && menuForm.id) {
    clonedTree = disableMenuAndChildren(clonedTree, menuForm.id)
  }
  
  const options = [
    {
      id: null,
      name: '顶级菜单',
      children: clonedTree
    }
  ]
  
  return options
})

// 获取菜单数据
const loadMenus = async (searchParams?: any) => {
  try {
    tableLoading.value = true
    const res = await getAllMenusApi(searchParams)
    if (res) {
      menuTree.value = Array.isArray(res) ? res : (res.data || res)
      filterMenus()
    }
  } catch (error) {
    ElMessage.error('获取菜单失败')
  } finally {
    tableLoading.value = false
  }
}

// 过滤菜单
const filterMenus = () => {
  filteredMenuTree.value = [...menuTree.value]
}

// 搜索
const handleSearch = () => {
  const searchParams = {
    menuName: searchForm.menuName,
    menuType: searchForm.menuType,
    status: searchForm.status
  }
  loadMenus(searchParams)
}

// 重置搜索
const handleReset = () => {
  searchForm.menuName = ''
  searchForm.menuType = undefined
  searchForm.status = undefined
  loadMenus()
}

// 刷新
const handleRefresh = () => {
  loadMenus()
}

// 分页相关
const handleSizeChange = (val: number) => {
  console.log(`${val} items per page`)
}

const handleCurrentChange = (val: number) => {
  console.log(`current page: ${val}`)
}

// 新增菜单
const handleAdd = () => {
  isEdit.value = false
  dialogTitle.value = '新增菜单'
  resetForm()
  dialogVisible.value = true
}

// 新增子菜单
const handleAddChild = (row: any) => {
  isEdit.value = false
  dialogTitle.value = '新增菜单'
  resetForm()
  menuForm.parentId = row.id
  dialogVisible.value = true
}

// 编辑菜单
const handleEdit = (row: any) => {
  isEdit.value = true
  dialogTitle.value = '编辑菜单'
  Object.assign(menuForm, row)
  dialogVisible.value = true
}

// 删除菜单
const handleDelete = (row: any) => {
  ElMessageBox.confirm(`确定要删除菜单"${row.name}"吗？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      deleteLoading.value = true
      currentDeleteId.value = row.id
  const res = await deleteMenuApi(row.id)
  ElMessage.success('删除成功')
  loadMenus()
    } catch (error) {
      ElMessage.error('删除失败')
    } finally {
      deleteLoading.value = false
      currentDeleteId.value = null
    }
  }).catch(() => {
    // 用户取消删除
  })
}

// 提交表单
const handleSubmit = () => {
  menuFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      try {
        submitLoading.value = true
        // 修正 parentId 类型，确保为 number 或 0
        const submitData = { ...menuForm, parentId: menuForm.parentId ? Number(menuForm.parentId) : 0 }
  const res = await saveMenuApi(submitData)
  ElMessage.success(isEdit.value ? '编辑成功' : '新增成功')
  dialogVisible.value = false
  loadMenus()
      } catch (error) {
        ElMessage.error(isEdit.value ? '编辑失败' : '新增失败')
      } finally {
        submitLoading.value = false
      }
    }
  })
}

// 重置表单
const resetForm = () => {
  Object.assign(menuForm, {
    id: undefined,
    name: '',
    path: '',
    component: '',
    icon: '',
    permission: '',
    menuType: 1,
    parentId: null,
    sort: 0,
    status: 1
  })
}

// 关闭对话框
const handleDialogClose = () => {
  resetForm()
}

// 初始化
onMounted(() => {
  loadMenus()
})

// 注册图标组件
const app = getCurrentInstance()?.appContext.app
if (app) {
  for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component)
  }
}
</script>

<style lang="less" scoped>
.menu-management-page {
  height: 100%;
  padding: 20px;
  box-sizing: border-box;
}

.main-card {
  height: 100%;
  display: flex;
  flex-direction: column;

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
  }

  :deep(.el-card__header) {
    flex-shrink: 0;
  }

  :deep(.el-card__body) {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding: 20px;
  }
}

.search-container {
  flex-shrink: 0;
  margin-bottom: 16px;
}

.table-container {
  flex: 1;
  min-height: 0;
  overflow: auto;
}

.menu-icon {
  color: #409eff;
}

:deep(.el-table) {
  .el-table__row {
    &:hover {
      background-color: #f5f7fa;
    }
  }
  
  .el-table__cell {
    padding: 8px 0;
    white-space: nowrap;
  }
  
  .el-table__cell .cell {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  
  .status-column {
    border-left: 1px solid #ebeef5;
  }
  
  .action-column {
    border-left: 1px solid #ebeef5;
  }
}
</style>